import java.util.LinkedList;
import java.util.Queue;
import java.util.concurrent.locks.Condition;
import java.util.concurrent.locks.ReentrantLock;

//阻塞队列
public class BlockingQueue {
    private final ReentrantLock lock = new ReentrantLock();
    private final Queue<Integer> queue = new LinkedList<>();
    private final int capacity;
    //生产者与消费者
    private final Condition producer = lock.newCondition();
    private final Condition consumer = lock.newCondition();
    public BlockingQueue(int capacity) {
        this.capacity = capacity;
    }
    //生产者
    public void enqueue(int element) throws InterruptedException {
        lock.lock();
        try {
            while(queue.size()==capacity){
                //阻塞
                producer.await();
            }
            //生产
            queue.add(element);
            //精确唤醒
            consumer.signal();
        } finally {
            lock.unlock();
        }
    }
    //消费者
    public int dequeue() throws InterruptedException {
        lock.lock();
        try {
            while(queue.size()==0){
                consumer.await();
            }
            //消费
            int value = queue.poll();
            producer.signal();
            return value;
        } finally {
            lock.unlock();
        }
    }

    public int size() {
        lock.lock();
        try {
            return queue.size();
        } finally {
            lock.unlock();
        }
    }


}
